﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace hw2_1
{
    // 银行类
    public class Bank
    {
        private string name;

        public Bank(string name)
        {
            this.name = name;
        }

        public string Name
        {
            get { return name; }
        }

        // 创建账户
        public Account CreateAccount(string accountNumber, string ownerName)
        {
            return new Account(accountNumber, ownerName);
        }
    }

    // 账户类
    public class Account
    {
        private string[] data = new string[3];
        private string accountNumber;
        private string ownerName;
        protected int balance;//子类可以修改
        private string[] keys = { "number", "owner", "balance" };

        //索引器
        public string this[int idx]
        {
            set
            {
                if (idx >= 0 && idx < data.Length)
                {
                    data[idx] = value;
                }
            }
            get
            {
                return (idx >= 0 && idx < data.Length) ? data[idx] : null;
            }
        }
        public string this[string key]
        {
            set
            {
                int idx = Array.IndexOf(keys, key);
                this[idx] = value;
            }
            get
            {
                return this[Array.IndexOf(keys,key)];
            }

        }

        public Account(string accountNumber, string ownerName)
        {
            this.accountNumber = accountNumber;
            this.ownerName = ownerName;
            this.balance = 0;
            this[0] = accountNumber;
            this[1] = ownerName;
            this[2] = balance.ToString();
        }

        public string AccountNumber
        {
            get { return accountNumber; }
        }

        public string OwnerName
        {
            get { return ownerName; }
        }

        public int Balance
        {
            get { return balance; }
        }

        // 存款
        public void Deposit(int amount)
        {
            balance += amount;
            this[2] = balance.ToString();
        }

        // 取款
        public virtual void Withdraw(int amount)
        {
            balance -= amount;
            if (balance < 0)
            {
                balance += amount;
                Console.WriteLine("警告！您的余额不足，目前为" + balance.ToString() + "元");
            }
            else
            {
                Console.WriteLine("成功取款" + amount.ToString() + "元");
            }
            this[2] = balance.ToString();
        }
    }

    //信用账号
    public class CreditAccount:Account
    {
        private int creditLimit;
        public int CreditLimit { 
            get{
                return creditLimit;
            }
        }
        public CreditAccount(string accountNumber, string ownerName) : base(accountNumber, ownerName)
        {
            this.creditLimit = 1000; // 设置默认信用额度为1000
        }
        public override void Withdraw(int amount)
        {
            if (Balance + creditLimit < amount)
            {
                Console.WriteLine("信用额度不足，无法取款！");
            }else if (amount < balance)
            {
                balance -= amount;
                Console.WriteLine("取款" + amount.ToString() + "元，余额为"+balance.ToString()+"元");
            }
            else
            {
                Console.WriteLine("余额不足，消耗信用额度" + (amount - balance).ToString() + "元");
                creditLimit = creditLimit-(amount - balance);
                balance = 0;
            }
        }
    }
    // 定义事件参数类BigMoneyArgs
    public class BigMoneyArgs : EventArgs
    {
        public Account Account { get; set; }
        public decimal Amount { get; set; }
    }

    // 定义委托类型BigMoneyFetchedHandler
    public delegate void BigMoneyFetchedHandler(object sender, BigMoneyArgs e);

    // ATM类
    public class ATM
    {
        private Bank bank;

        public ATM(Bank bank)
        {
            this.bank = bank;
            OnBigMoneyFetched+=new BigMoneyFetchedHandler(bigMoneyWarn);
        }
        // 定义事件BigMoneyFetched
        public event BigMoneyFetchedHandler OnBigMoneyFetched;

        void bigMoneyWarn(object sender, BigMoneyArgs e)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("取款金额大于10000，注意资金安全！");
            Console.ResetColor();  // 重置颜色为默认颜色
        }

        // 通过账号和密码验证身份
        private bool Authenticate(Account account, string password)
        {
            // 假设均是正确的
            return true;
        }

        // 取款操作
        public void Withdraw(Account account, string password, int amount)
        {
            if (Authenticate(account, password))
            {
                if (amount > 10000)
                {
                    OnBigMoneyFetched(this, new BigMoneyArgs { Account = account, Amount = amount });
                }
                //ATM取款时30%坏钞率
                try
                {
                    // 模拟坏钞率
                    Random random = new Random();
                    if (random.Next(1, 101) <= 30)
                    {
                        throw new BadCashException("发现了一张坏钞！");
                    }
                }catch(BadCashException be)
                {
                    Console.WriteLine("发现损坏钞票！");
                }
                finally
                {
                    account.Withdraw(amount);
                    Console.WriteLine("余额为: " + account.Balance);
                }
            }
            else
            {
                Console.WriteLine("密码或账户错误！");
            }
        }
    }
    // 自定义异常类BadCashException
    public class BadCashException : Exception
    {
        public BadCashException(string message) : base(message) { }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            //验证索引器
            Account a = new Account("123456","张三");
            Console.WriteLine(a["owner"]);
            a.Deposit(1000);
            Console.WriteLine(a["balance"]);

            //测试信用账户
            CreditAccount ca = new CreditAccount("111111", "李四");
            ca.Deposit(6000);
            Console.WriteLine("余额为"+ca.Balance.ToString()+"元");
            ca.Withdraw(8000);
            Console.WriteLine("余额为"+ca.Balance.ToString()+"元");
            ca.Withdraw(4000);
            Console.WriteLine("余额为"+ ca.Balance.ToString()+ "元");
            ca.Withdraw(2400);
            Console.WriteLine("余额为"+ ca.Balance.ToString()+ "元");
            Console.WriteLine("信用额度为"+ ca.CreditLimit.ToString()+ "元");

            //测试万元以上事件委托
            ATM atm = new ATM(new Bank("浦发银行"));
            atm.Withdraw(a,"pwd" ,400);
            atm.Withdraw(a,"pwd" , 12000);

            Console.Read();
        }
    }
}
